-
Endianness defines how multi-byte values are laid out in memory—specifically, the order in which bytes are stored.
-
Endianness decides which byte goes at the lowest memory address.
-
It's about the BYTE order, not the BIT order inside the bytes.
-
Inside a single byte, the bit positions are fixed:
bit index: 7 6 5 4 3 2 1 0 value: 128 ... 1-
That mapping (MSB ↔ bit 7, LSB ↔ bit 0) is unchanged regardless of endianness.
-
Little-endian (reversed byte order in memory / "little byte comes first")
-
Least significant byte stored first (lowest address)
-
Most systems today are little-endian.
value: 0x12345678
Address: +0 +1 +2 +3
Memory: 78 56 34 12 (little-endian)
-
Used by:
-
x86 / x86-64
-
ARM (default today)
-
most modern systems
-
Why
-
Carry propagation naturally walks forward in memory.
-
A pointer to a larger integer can be reinterpreted as a smaller one without adjusting the address.
-
Example: reading a u8 from a u32* just reads the first byte (LSB).
-
-
Early CPUs like the Intel 8086 used little-endian.
-
Their internal design made it natural to fetch/store the low byte first.
-
Success of x86 cemented little-endian as the de facto standard.
-
-
Operations that grow precision (e.g. multi-precision arithmetic) can extend “forward” in memory.
-
Useful for things like bignum libraries.
-
-
The dominance of little-endian is mostly inertia:
-
x86 (little-endian) became ubiquitous in desktops/servers.
-
ARM defaults to little-endian in almost all modern systems.
-
Toolchains, file formats, and OS ecosystems followed.
-
Big-endian (same order you write numbers / "big byte comes first")
-
Most significant byte first
Value: 0x12345678
Address: +0 +1 +2 +3
Memory: 12 34 56 78
-
Used by:
-
Networking protocols (e.g. TCP/IP)
-
older architectures (e.g., PowerPC in certain modes)
-
Why
-
Big-endian isn’t worse—just optimized for different priorities:
-
Memory layout matches human-readable order (easier debugging).
-
Network protocols standardized on it → “network byte order”.
-
Some architectures (older PowerPC, SPARC) favored it.
-
Examples
String8
-
Endianness only matters once you break 16-bit units into bytes. For 8-bit strings, there’s no ambiguity.
-
No endianness concerns here.
'o' = 01101111 = 0x6F
'i' = 01101001 = 0x69
null = 00000000 = 0x00
-
oi\0instring8
"oi" → 01101111 01101001 00000000
String16
'o' = 0x006F -> 0x6F00 (little-endian) / 0x006F (big-endian)
'i' = 0x0069 -> 0x6900 (little-endian) / 0x0069 (big-endian)
null = 0x0000 -> 0x0000
-
oi\0in little-endian
"oi" → 01101111 00000000 01101001 00000000 00000000 00000000
-
oi\0in big-endian
"oi" → 00000000 01101111 00000000 01101001 00000000 00000000